// File Player.cpp
//
// Purpose: Class defining the player and his/her data
//
// Author : Bryson King (edited)
// Original Code Provided by: Mat Buckland 2002 (fup@ai-junkie.com)
// Date : 18 March 2013
// --------------------------------------------------------------
#define DEBUG_SECTION

#include "Player.h"

#include <string>
#include <cassert>
#include <iostream>

#include "misc/ConsoleUtils.h"

#include "BaseGameEntity.h"
#include "EntityNames.h"
#include "IPerson.h"
#include "Item.h"
#include "LocationMachine.h"
#include "Locations.h"
#include "PlayerStates.h"
#include "StateMachine.h"

CPlayer::CPlayer(int id) : CBaseGameEntity(id), IPerson(), m_iHealth(MaxHealthLevelForPlayer)
{
	//set up state machine
	m_pStateMachine = new CStateMachine<CPlayer>(this);
	m_pLocationMachine = new CLocationMachine(this);
	m_pStateMachine->SetCurrentState(Startup::Instance());
	m_pLocationMachine->SetCurrentLocation(EDivBerthing::Instance());
	// Add player to the correct location
	EDivBerthing::Instance()->AddEntityToLocation(this);
}
CPlayer::~CPlayer()
{
	delete m_pStateMachine;
	delete m_pLocationMachine;
}

bool CPlayer::HandleMessage(const Telegram& msg)
{
	return m_pStateMachine->HandleMessage(msg);
}

void CPlayer::Update()
{
	string sUserInput;
	SItem* itemReturned;
	IPerson* pEnemy = nullptr;
	
	SetTextColor(FOREGROUND_GREEN| FOREGROUND_INTENSITY);
	//m_pStateMachine->Update();
	m_pLocationMachine->Update();

	// Check to see if currently in combat and work accordingly
	if (CUserInterface::InCombat)
	{
		CUserInterface::CombatInterface(this, nullptr, true);
	} else { // If not in combat, allow user to determine next option
		//request input from the user based on what options are available.
		itemReturned = m_pLocationMachine->CurrentLocation()->RequestUserInput(this, sUserInput, pEnemy);

		//call function to check inventory if appropriate
		if (sUserInput == "INVENTORY")
		{
			CheckInventory();
		}
		// Begin a combat with a foe
		else if (sUserInput == "ATTACK")
		{
			StartCombat();
			pEnemy->StartCombat();
			CUserInterface::CombatInterface(this, pEnemy, true);
		}
		// Search the downed foe
		else if (sUserInput == "SEARCH")
		{
			EndCombat();
			pEnemy->EndCombat();
			CUserInterface::SearchEntity(this, pEnemy);
		}
		else if (itemReturned != nullptr)
		{
			AddItemToInventory(itemReturned);
		}
	}
}

void CPlayer::CheckInventory()
{
	// Output inventory to console
	SetTextColor(BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
	
	cout << endl;
	cout << "Your inventory contains the following:" << endl;
	cout << endl;
	cout << m_oInventory.ListItems();
	cout << endl;
}

CStateMachine<CPlayer>* CPlayer::GetFSM() const
{
	return m_pStateMachine;
}

CLocationMachine* CPlayer::GetLocationMachine() const
{
	return m_pLocationMachine;
}

std::string CPlayer::Name() const
{
	return GetNameOfEntity(this->ID());
}

int CPlayer::GetID() const
{
	return this->ID();
}

//-------------------------------------------------------------accessors
void CPlayer::SetHealth(int val)
{
	m_iHealth = val;
}

int CPlayer::Health() const
{
	return m_iHealth;
}
